package com.clarence.dada.modular.system.config.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.clarence.dada.core.base.PageResult;
import com.clarence.dada.core.enums.ErrorEnum;
import com.clarence.dada.core.enums.StatusEnum;
import com.clarence.dada.core.enums.YesOrNotEnum;
import com.clarence.dada.core.exception.BusException;
import com.clarence.dada.core.factory.PageFactory;
import com.clarence.dada.core.factory.PageResultFactory;
import com.clarence.dada.modular.system.config.entity.SysConfigEntity;
import com.clarence.dada.modular.system.config.entity.req.SysConfigReq;
import com.clarence.dada.modular.system.config.entity.resp.SysConfigResp;
import com.clarence.dada.modular.system.config.mapper.SysConfigMapper;
import com.clarence.dada.modular.system.config.service.SysConfigService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 系统参数配置service接口实现类
 *
 * @author GD
 * @since 2020/4/14 11:16
 */
@Service
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfigEntity> implements SysConfigService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void configAdd(SysConfigReq req) {
        // 1.构造实体
        SysConfigEntity sysConfig = Convert.convert(SysConfigEntity.class, req);
        sysConfig.setStatusFlag(StatusEnum.ENABLE.getCode());

        // 2.保存到库中
        this.save(sysConfig);

        // 3.添加对应context
//        ConfigContext.me().putConfig(req.getConfigCode(), req.getConfigValue());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void configEdit(SysConfigReq req) {

        // 1.根据id获取常量信息
        SysConfigEntity sysConfig = this.querySysConfig(req);

        // 2.请求参数转化为实体,不能修改状态，用修改状态接口修改状态
        BeanUtil.copyProperties(req, sysConfig);
        sysConfig.setStatusFlag(null);

        // 3.更新记录
        this.updateById(sysConfig);
//
//        // 4.更新对应常量context
//        ConfigContext.me().putConfig(req.getConfigCode(), req.getConfigValue());
//
//        // 5.发布属性修改的事件
//        try {
//            Map<String, ConfigUpdateCallback> beansOfType = SpringUtil.getBeansOfType(ConfigUpdateCallback.class);
//            for (ConfigUpdateCallback value : beansOfType.values()) {
//                value.configUpdate(sysConfig.getConfigCode(), sysConfig.getConfigValue());
//            }
//        } catch (Exception e) {
//            // 忽略找不到Bean的异常
//        }
    }

    @Override
    public SysConfigResp configDetail(SysConfigReq req) {
        SysConfigEntity configEntity = this.querySysConfig(req);
        return Convert.convert(SysConfigResp.class, configEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void configDelete(SysConfigReq req) {
        // 1.根据id获取常量、同时不能删除系统参数
        SysConfigEntity sysConfig = this.querySysConfig(req);
        if (YesOrNotEnum.Y.getCode().equals(sysConfig.getSysFlag())) {
            throw new BusException(ErrorEnum.CONFIG_SYS_CAN_NOT_DELETE);
        }

        // 2.设置状态为已删除
        sysConfig.setStatusFlag(StatusEnum.DISABLE.getCode());
        sysConfig.setDelFlag(YesOrNotEnum.Y.getCode());
        this.updateById(sysConfig);

        // 4.删除对应context
//        ConfigContext.me().deleteConfig(sysConfigParam.getConfigCode());
    }

    @Override
    public PageResult<SysConfigResp> configPage(SysConfigReq req) {
        LambdaQueryWrapper<SysConfigEntity> wrapper = createWrapper(req);
        Page<SysConfigEntity> page = this.page(PageFactory.defaultPage(), wrapper);
        List<SysConfigResp> respList = Convert.convert(new TypeReference<>() {}, page.getRecords());
        return PageResultFactory.result(page, respList);
    }

    @Override
    public List<SysConfigEntity> findList(SysConfigReq req) {
        LambdaQueryWrapper<SysConfigEntity> wrapper = createWrapper(req);
        return this.list(wrapper);
    }
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void initConfig(ConfigInitRequest configInitRequest) {
//
//        if (configInitRequest == null || configInitRequest.getSysConfigs() == null) {
//            throw new ConfigException(ConfigExceptionEnum.CONFIG_INIT_ERROR);
//        }
//
//        // 如果当前已经初始化过配置，则不能初始化
//        LambdaQueryWrapper<SysConfig> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.eq(SysConfig::getConfigCode, RuleConstants.SYSTEM_CONFIG_INIT_FLAG_NAME);
//        SysConfig tempSysConfig = this.getOne(lambdaQueryWrapper, false);
//        String alreadyInit = tempSysConfig.getConfigValue();
//        if (Convert.toBool(alreadyInit)) {
//            throw new ConfigException(ConfigExceptionEnum.CONFIG_INIT_ALREADY);
//        }
//
//        // 获取初始化回调接口的所有实现类
//        Map<String, ConfigInitCallbackApi> beans = SpringUtil.getBeansOfType(ConfigInitCallbackApi.class);
//
//        // 调用初始化之前回调
//        if (ObjectUtil.isNotNull(beans)) {
//            for (ConfigInitCallbackApi initCallbackApi : beans.values()) {
//                initCallbackApi.initBefore();
//            }
//        }
//
//        // 添加系统已经初始化的配置
//        Map<String, String> sysConfigs = configInitRequest.getSysConfigs();
//        sysConfigs.put(RuleConstants.SYSTEM_CONFIG_INIT_FLAG_NAME, "true");
//
//        // 针对每个配置执行更新库和刷新缓存的操作
//        for (Map.Entry<String, String> entry : sysConfigs.entrySet()) {
//            String configCode = entry.getKey();
//            String configValue = entry.getValue();
//
//            // 获取库数据库这条记录
//            LambdaQueryWrapper<SysConfig> wrapper = new LambdaQueryWrapper<>();
//            wrapper.eq(SysConfig::getConfigCode, configCode);
//            SysConfig sysConfig = this.getOne(wrapper, false);
//            if (sysConfig == null) {
//                continue;
//            }
//            sysConfig.setConfigValue(configValue);
//            this.updateById(sysConfig);
//
//            // 更新缓存
//            ConfigContext.me().putConfig(configCode, configValue);
//        }
//
//        // 调用初始化之后回调
//        if (ObjectUtil.isNotNull(beans)) {
//            for (ConfigInitCallbackApi initCallbackApi : beans.values()) {
//                initCallbackApi.initAfter();
//            }
//        }
//    }
//
//    @Override
//    public Boolean getInitConfigFlag() {
//        LambdaQueryWrapper<SysConfigEntity> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(SysConfigEntity::getConfigCode, RuleConstants.SYSTEM_CONFIG_INIT_FLAG_NAME);
//        SysConfigEntity sysConfig = this.getOne(wrapper, false);
//
//        // 配置为空，还没初始化
//        if (sysConfig == null) {
//            return true;
//        } else {
//            String configValue = sysConfig.getConfigValue();
//            if (StrUtil.isEmpty(configValue)) {
//                return true;
//            } else {
//                return Convert.toBool(sysConfig.getConfigValue());
//            }
//        }
//    }

//    @Override
//    public InitConfigResponse getInitConfigs() {
//
//        InitConfigResponse initConfigResponse = new InitConfigResponse();
//        initConfigResponse.setTitle("首次运行参数生成");
//        initConfigResponse.setDescription("第一次进入Guns系统会配置系统的一些秘钥和部署的url信息，这些秘钥均为随机生成，以确保系统的安全性");
//
//        // 获取所有参数分组下的配置信息
//        List<InitConfigGroup> configGroupList = new ArrayList<>();
//        Map<String, ConfigInitStrategyApi> beans = SpringUtil.getBeansOfType(ConfigInitStrategyApi.class);
//        for (ConfigInitStrategyApi value : beans.values()) {
//            String title = value.getTitle();
//            String description = value.getDescription();
//            List<ConfigInitItem> initConfigs = value.getInitConfigs();
//            configGroupList.add(new InitConfigGroup(title, description, initConfigs));
//        }
//        initConfigResponse.setInitConfigGroupList(configGroupList);
//
//        return initConfigResponse;
//    }
//
//    @Override
//    public String getServerDeployHost() {
//
//        // 获取后端部署的服务器
//        LambdaQueryWrapper<SysConfigEntity> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(SysConfigEntity::getConfigCode, ConfigConstants.SYS_SERVER_DEPLOY_HOST);
//        SysConfigEntity sysConfig = this.getOne(wrapper, false);
//
//        if (sysConfig != null) {
//            return sysConfig.getConfigValue();
//        } else {
//            return FileConstants.DEFAULT_SERVER_DEPLOY_HOST;
//        }
//    }

    /**
     * 获取系统参数配置
     *
     * @author GD
     * @since 2020/4/14 11:19
     */
    public SysConfigEntity querySysConfig(SysConfigReq req) {
        SysConfigEntity sysConfig = this.getById(req.getConfigId());
        if (ObjectUtil.isEmpty(sysConfig) || sysConfig.getDelFlag().equals(YesOrNotEnum.Y.getCode())) {
            throw new BusException(ErrorEnum.CONFIG_NOT_EXIST);
        }
        return sysConfig;
    }

    /**
     * 创建wrapper
     *
     * @author GD
     * @since 2020/11/6 10:16
     */
    private LambdaQueryWrapper<SysConfigEntity> createWrapper(SysConfigReq req) {
        LambdaQueryWrapper<SysConfigEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(SysConfigEntity::getDelFlag, YesOrNotEnum.Y.getCode())
                .orderByDesc(SysConfigEntity::getGroupCode);

        if (ObjectUtil.isEmpty(req)) {
            return queryWrapper;
        }
        queryWrapper.like(StrUtil.isNotBlank(req.getConfigName()), SysConfigEntity::getConfigName, req.getConfigName())
                .like(StrUtil.isNotBlank(req.getConfigCode()), SysConfigEntity::getConfigCode, req.getConfigCode())
                .eq(StrUtil.isNotBlank(req.getGroupCode()), SysConfigEntity::getGroupCode, req.getGroupCode());
        return queryWrapper;
    }

}
